package com.link.gateway.core.filter.global;

import com.link.gateway.core.comproperty.FilterOrderConstants;
import com.link.gateway.core.comproperty.InterfaceLogConstants;
import com.link.gateway.core.comproperty.OtherConstants;
import com.link.gateway.core.comproperty.TokenConstants;
import com.link.gateway.core.utils.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;


/**
 * @author guoshan
 * @date 2019年07月18日
 * 对请求头进行处理：避免携带不应该携带的请求头；判断ip是否在黑白名单中，然后进行处理
 * 处理非法请求
 */
@Component
public class LinkReqHeaderFilter implements GlobalFilter, Ordered {
    private static final Logger logger = LogManager.getLogger(LinkReqHeaderFilter.class);
    private static final String[] illegalHeader = {TokenConstants.NO_INTERCEPT_FLAG_NAME};

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //跳过检测
        Object ignoreGlobalFilter = exchange.getAttribute(OtherConstants.ATTRIBUTE_IGNORE_GLOBAL_FILTER);
        if (ignoreGlobalFilter != null && (boolean)ignoreGlobalFilter) {
            return chain.filter(exchange);
        }

        //HuangLJ 2019年07月28日

        long clearVarBegin = System.currentTimeMillis();
        TokenUtils.postHandle();
        ServerHttpResponse response = exchange.getResponse();
        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();

        /**
         * 判断是否含有非法请求头
         */
        for (String header : illegalHeader) {
            boolean allowVisit = headers.containsKey(header);
            if (allowVisit) {
                response.setStatusCode(HttpStatus.FORBIDDEN);
                // 回写"当前的域名非法！"
                return ResponseDataUtils.writeWith(InterfaceLogConstants.HEADER_OVER, "含有非法请求头！", "Y", exchange, null);
            }
        }

        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            long clearVarEnd = System.currentTimeMillis();
            //post操作。当所有请求执行完成之后，把该移除的线程变量等移除
            logger.debug("first post filter");
            FunctionTimeUtil.functionTime("LinkRequestHeaderFilterPost", "LinkRequestHeaderFilter", clearVarBegin, clearVarEnd,false);

        }));
    }

    @Override
    public int getOrder() {
        return FilterOrderConstants.HEADER_MANAGER_ORDER;
    }
}
